<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use PHPSocketIO\SocketIO;

$ws_object=[];
//加载所有模块文件
$module_dir='./modules/';
$files=scandir($module_dir);
foreach ($files as $file) {
    if ($file=='.' || $file=='..') {
        continue;
    }
    if (pathinfo($file, PATHINFO_EXTENSION)!='php') {
        continue;
    }
    
    include($module_dir.$file);
    $filename=pathinfo($file, PATHINFO_FILENAME);
    $ws_object[$filename]=new $filename();
}
include('./hooks.php');
// 创建socket.io服务端，监听3120端口
$context = array(
    // 'ssl' => array(
    //     'local_cert'  => '/your/path/of/server.pem',
    //     'local_pk'    => '/your/path/of/server.key',
    //     'verify_peer' => false,
    // )
);
$io = new SocketIO(3120, $context);
// $io->origins('http://example.com:8080');
// 当有客户端连接时打印一行文字
$io->on('connection', function ($connection) use ($io) {
    connection($io, $connection);

    $connection->on('ttl', function ($msg) use ($io,$connection) {
        ttl($io, $connection);
    });

    $connection->on('message', function ($msg) use ($io,$connection) {
        global $ws_object;
        $msg=json_decode($msg, true);
        if ($msg===null) {
            $connection->emit('message', ['code'=> '403','msg'=> 'lose data!']);
            return;
        }
        isset($msg['controller']) or $msg['controller']='index';
        isset($msg['action']) or $msg['action']='index';
        isset($msg['data']) or $msg['data']=[];

        $controller=$msg['controller'].'Controller';
        $action=$msg['action'];
        $data=$msg['data'];
        if (!array_key_exists($controller, $ws_object)) {
            $connection->emit('message', ['code'=> '404','msg'=> 'call not defined controller/action!']);
            return;
        }
        if (!method_exists($ws_object[$controller], $action)) {
            $connection->emit('message', ['code'=> '404','msg'=> 'call not defined controller/action!']);
            return;
        }
        $ref=new ReflectionMethod($ws_object[$controller], $action);
        $deny_list=array('__construct','__destruct','__call','__callStatic','__get','__set','__isset','__unset','__sleep','__wakeup','__toString','__invoke','__set_state','__clone');
        if (!$ref->isPublic() || in_array($action, $deny_list)) {
            $connection->emit('message', ['code'=> '404','msg'=> 'call not defined controller/action!']);
            return;
        }
        $ws_object[$controller]->$action($io, $connection, $data);
    });

    $connection->on('disconnect', function ($connection) use ($io) {
        disconnect($io, $connection);
    });
});


// $io->on('connection', function ($connection) use ($io) {
//     echo "new connection coming\n";
//     $connection->on('hello', function ($msg) use ($io,$connection) {
//         echo "hello ".$msg."\n";
//         $connection->emit('hello', '你好');
//     });

//     $connection->on('ping2', function ($msg) use ($io,$connection) {
//         echo "receive ping\n";
//         $connection->emit('ping2', 'pong');
//     });

//     $connection->on('disconnect', function ($connection) use ($io) {
//         echo "goodbye\n";
//     });
// });

Worker::runAll();
